﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using BrightIdeasSoftware;
using GzipManagerPro.UI.Utility;

namespace GzipManagerPro.UI.Controls
{
    public class FileSystemExplorerProvider: System.ComponentModel.Component, IExplorerProvider
    {
        private Explorer Explorer;
        private BrightIdeasSoftware.OLVColumn ColumnName;
        private BrightIdeasSoftware.OLVColumn ColumnModified;
        private BrightIdeasSoftware.OLVColumn ColumnSize;
        private BrightIdeasSoftware.OLVColumn ColumnFileType;

        public void Initialize(Explorer explorer)
        {
            this.Explorer = explorer;

            this.ColumnName = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
            this.ColumnModified = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
            this.ColumnSize = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
            this.ColumnFileType = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));

            explorer.Columns.Add(this.ColumnName);
            explorer.Columns.Add(this.ColumnModified);
            explorer.Columns.Add(this.ColumnSize);
            explorer.Columns.Add(this.ColumnFileType);

            // 
            // ColumnName
            // 
            this.ColumnName.AspectName = "Name";
            this.ColumnName.CellPadding = null;
            this.ColumnName.IsTileViewColumn = true;
            this.ColumnName.Text = "Name";
            this.ColumnName.UseInitialLetterForGroup = true;
            this.ColumnName.Width = 180;
            this.ColumnName.WordWrap = true;
            // 
            // ColumnModified
            // 
            this.ColumnModified.AspectName = "LastWriteTime";
            this.ColumnModified.CellPadding = null;
            this.ColumnModified.DisplayIndex = 1;
            this.ColumnModified.IsTileViewColumn = true;
            this.ColumnModified.Text = "Modified";
            this.ColumnModified.Width = 145;
            // 
            // ColumnSize
            // 
            this.ColumnSize.AspectName = "Extension";
            this.ColumnSize.CellPadding = null;
            this.ColumnSize.DisplayIndex = 2;
            this.ColumnSize.HeaderTextAlign = System.Windows.Forms.HorizontalAlignment.Right;
            this.ColumnSize.Text = "Size";
            this.ColumnSize.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
            this.ColumnSize.Width = 80;
            // 
            // ColumnFileType
            // 
            this.ColumnFileType.CellPadding = null;
            this.ColumnFileType.DisplayIndex = 3;
            this.ColumnFileType.IsTileViewColumn = true;
            this.ColumnFileType.Text = "File Type";
            this.ColumnFileType.Width = 148;

            

            explorer.HideSelection = false;
            explorer.CanExpandGetter = delegate(object x)
            {
                return ((CustomFileSystemInfo)x).IsDirectory;
            };
            explorer.ChildrenGetter = delegate(object x)
            {
                CustomFileSystemInfo myFileSystemInfo = (CustomFileSystemInfo)x;
                try
                {
                    return myFileSystemInfo.GetFileSystemInfos();
                }
                catch (UnauthorizedAccessException ex)
                {
                    ex.MessageBox();
                    return new ArrayList();
                }
            };

            //explorer.CheckBoxes = false;

            // You can change the way the connection lines are drawn by changing the pen
            BrightIdeasSoftware.TreeListView.TreeRenderer renderer = explorer.TreeColumnRenderer;
            renderer.LinePen = new Pen(SystemColors.ControlDark, 0.5f);
            renderer.LinePen.DashStyle = DashStyle.Dot;

            //-------------------------------------------------------------------
            // Eveything after this is the same as the Explorer example tab --
            // nothing specific to the TreeListView. It doesn't have the grouping
            // delegates, since TreeListViews can't show groups.

            // Draw the system icon next to the name
            SysImageListHelper helper = new SysImageListHelper(explorer);
            this.ColumnName.ImageGetter = delegate(object x)
            {
                try
                {
                    return helper.GetImageIndex(((CustomFileSystemInfo)x).FullName);
                }
                catch (Exception ex)
                {
                    ex.MessageBox();
                    return string.Empty;
                }
            };

            // Show the size of files as GB, MB and KBs. Also, group them by
            // some meaningless divisions
            this.ColumnSize.AspectGetter = delegate(object x)
            {
                CustomFileSystemInfo myFileSystemInfo = (CustomFileSystemInfo)x;

                if (myFileSystemInfo.IsDirectory)
                    return (long)-1;

                try
                {
                    return myFileSystemInfo.Length;
                }
                catch (System.IO.FileNotFoundException)
                {
                    // Mono 1.2.6 throws this for hidden files
                    return (long)-2;
                }
            };
            this.ColumnSize.AspectToStringConverter = delegate(object x)
            {
                if ((long)x == -1) // folder
                    return "";

                return explorer.FormatFileSize((long)x);
            };

            // Show the system description for this object
            this.ColumnFileType.AspectGetter = delegate(object x)
            {
                return ShellUtilities.GetFileType(((CustomFileSystemInfo)x).FullName);
            };

            
            // List all drives as the roots of the tree
            ArrayList roots = new ArrayList();
            foreach (DriveInfo di in DriveInfo.GetDrives())
                roots.Add(new CustomFileSystemInfo(new DirectoryInfo(di.Name)));
            
            explorer.Roots = roots;
        }
    }
}
